import PackageAPI from '@/api/Package';
import {
  Box,
  DragAndDropProvider,
  DraggableItem,
  DragHandle,
  DroppableContainer,
  FieldCols,
  FieldEffect,
  FormSection,
  Icon,
  mapField,
  ModalSelectTable,
  PopoverConfirm,
  useCall,
  useFormValue,
  useQueryValue,
  useReq,
  useSimpleMemo,
} from '@/components';
import { companyFields } from '@/constants/sharedFields';
import { pathJoin } from '@/utils';
import { catchAndScrollFor } from '@/utils/fp';
import { Button, Form, message, Space, Spin, Table } from 'antd';
import React, { createContext, useContext, useEffect, useMemo, useRef } from 'react';

const Context = createContext({ form: null, packageCode: null });

const FIELDS = [
  [
    'packageCode',
    '组合编码',
    null,
    {
      readOnly: true,
      getColProps() {
        const { packageCode } = useContext(Context);
        return { hidden: !packageCode };
      },
    },
  ],

  ['packageName', '组合名称', null, { required: true }],
  ...companyFields,

  // ['saleStateMark', '组合状态'],
  // ['saleBeginTime', '销售日期', 'date', { getValueProps: dateToMomentProp, getValueFromEvent:
  // momentToDate('start') }], ['saleEndTime', '停售日期', 'date', { getValueProps: dateToMomentProp,
  // getValueFromEvent: momentToDate('end') }],
].map(mapField);

function SelectPlans(props) {
  const fields = useMemo(
    () =>
      [
        [['searchFuzzy', 'plan_business_code'], '计划业务编码'],
        [['searchFuzzy', 'plan_code'], '计划编码'],
        [['searchFuzzy', 'plan_name'], '计划名称'],
      ].map(mapField),
    [],
  );

  const columns = useMemo(
    () => [
      { dataIndex: 'planBusinessCode', title: '计划业务编码', width: 120 },
      { dataIndex: 'planCode', title: '计划编码', width: 120 },
      { dataIndex: 'companyName', title: '保险公司', width: 110, ellipsis: true },
      { dataIndex: 'planName', title: '计划名称', width: 160 },
    ],
    [],
  );

  return (
    <ModalSelectTable
      title='计划'
      {...props}
      service={PackageAPI.selectPlans}
      rowKey='planBusinessCode'
      fields={fields}
      columns={columns}
    />
  );
}

function Plans() {
  const { form } = useContext(Context);
  const companyCode = useFormValue(form, 'companyCode');
  const selected = useFormValue(form, 'plans', (v) => v?.map((t) => t.planBusinessCode) ?? []);
  const onAdd = useCall((plans) => {
    const oldPlans = form.getFieldValue('plans') ?? [];
    const oldPlanCodes = oldPlans?.map((v) => v.planBusinessCode);
    const newPlans = oldPlans.concat(plans.filter((v) => !oldPlanCodes.includes(v.planBusinessCode)));
    form.setFieldsValue({ plans: newPlans });
  });

  const getList = useRef(() => form.getFieldValue('plans')?.slice() ?? []).current;

  const columns = useMemo(
    () => [
      {
        key: 'rm',
        align: 'center',
        width: 64,
        render(col, row, index) {
          return (
            <PopoverConfirm
              onOk={() => {
                const prodList = getList();
                prodList.splice(index, 1);
                form.setFieldsValue({ plans: prodList });
              }}
            >
              <Button size='small' type='text'>
                <Icon type='delete' />
              </Button>
            </PopoverConfirm>
          );
        },
      },
      {
        key: 'sort',
        align: 'center',
        title: '排序',
        width: 64,
        render() {
          return (
            <DragHandle>
              <Button size='small' type='text'>
                <Icon type='menu' />
              </Button>
            </DragHandle>
          );
        },
      },
      { dataIndex: 'planBusinessCode', title: '计划业务编码', width: 160 },
      { dataIndex: 'planCode', title: '计划编码', width: 160 },
      { dataIndex: 'planName', title: '计划名称' },
    ],
    [],
  );

  const tableProps = useMemo(
    () => ({
      components: {
        body: {
          row: DraggableItem,
        },
      },
      onRow: (row, index) => ({ row, index }),
    }),
    [],
  );

  const config = useMemo(
    () => ({
      rowKey: 'id',
      itemComponent: 'tr',
      getDroppableKeys() {
        return getList().map((v) => v.id);
      },
      onDrop(rowCtx, currentIndex, all) {
        const prodList = getList();
        const [item] = prodList.splice(rowCtx.index, 1);
        prodList.splice(currentIndex, 0, item);
        form.setFieldsValue({ plans: prodList });
      },
    }),
    [],
  );

  const onService = useCall((formData) => [{ ...formData, t: { ...formData.t, companyCode } }]);

  const dataSource = useFormValue(form, 'plans');

  return (
    <>
      <FieldEffect name='plans' initialValue={[]} />

      <Box>
        <SelectPlans selectType='checkbox' onService={onService} onOk={onAdd}>
          <Button type='primary'>+ 新 增</Button>
        </SelectPlans>
        <Box py={1} />
      </Box>

      <DragAndDropProvider {...config}>
        <DroppableContainer>
          <Table
            rowKey='id'
            dataSource={dataSource}
            columns={columns}
            size='middle'
            pagination={false}
            {...tableProps}
          />
        </DroppableContainer>
      </DragAndDropProvider>
    </>
  );
}

function AddPage({ history, location }) {
  const packageCode = useQueryValue('packageCode');
  const [form] = Form.useForm();
  const xhr = useReq(PackageAPI.getByCode);
  const saveXhr = useReq(PackageAPI.svaOrUpdate);

  useEffect(() => {
    if (packageCode) {
      xhr.start(packageCode).then((res) => {
        if (res.data) form.setFieldsValue(res.data);
      });
    }
  }, [packageCode]);

  const handleSave = useCall(async () => {
    const values = await form.validateFields().catch(catchAndScrollFor(form));
    if (!values.plans?.length) {
      message.warn('请至添加一个计划');
      return false;
    }

    await saveXhr.start({ ...(xhr.result?.data ?? null), ...values });

    message.success('保存成功');
    history.replace(pathJoin(location.pathname, '../'));
  });

  const context = useSimpleMemo({ form, packageCode });
  const loading = [xhr.status, saveXhr.status].includes('loading');

  return (
    <Context.Provider value={context}>
      <Spin spinning={loading}>
        <Form form={form}>
          <FormSection title='组合配置'>
            <FieldCols form={form} fields={FIELDS} />
          </FormSection>

          <FormSection title='计划'>
            <Plans />
          </FormSection>

          <Box flex jus='center' py={3} className='form-page-btn'>
            <Space size='large'>
              <Button onClick={history.goBack}>返回</Button>
              <Button type='primary' onClick={handleSave}>
                保存
              </Button>
            </Space>
          </Box>
        </Form>
      </Spin>
    </Context.Provider>
  );
}

export default AddPage;
